import {createComponent, inject, onBeforeUnmount, onMounted} from "@vue/composition-api";
import {useEditorPlugins, VueFlowEditorProvider} from "@/editor/editor";
import {G6} from "@/g6/g6";
import {useBehavior} from "@/behavior";
import {GraphStyle} from "@/utils/styles";
import {registerShape} from "@/shape";
import {DEFAULT_SIZE, formatNodeModel} from "@/utils/utils";

registerShape(G6)

export default createComponent({
    name: 'vue-flow-editor-canvas',
    props: {
        data: {type: Object},                                                                // 渲染的数据

        miniMap: {type: [Boolean, Object], default: true},                                  // 是否需要缩略图
        grid: {type: [Boolean, Object], default: true},                                     // 是否需要网格
    },
    setup(props, context) {

        const {editorState, commander, props: editorProps} = inject(VueFlowEditorProvider) as any

        function onMouseenter(e: MouseEvent) {commander.initEvent()}

        function onMouseout(e: MouseEvent) {commander.destroyEvent()}

        function refresh() {
            if (!!editorState.graph) {
                editorState.graph.destroy()
            }
            const target = context.refs.target as HTMLElement
            const {offsetHeight: height, offsetWidth: width} = context.refs.root as HTMLElement
            const behaviors = useBehavior({
                multipleSelect: editorState.props.multipleSelect,
                dragEdge: {
                    disabled: editorState.props.disabledDragEdge,
                    beforeAdd: editorState.props.beforeAdd,
                    afterAdd: editorState.props.afterAdd,
                }
            })

            const graph = new G6.Graph({
                container: target as HTMLElement,
                width,
                height,

                modes: {
                    edit: [
                        ...behaviors,
                    ],
                },

                ...GraphStyle.default,
            })

            const $read = graph.read
            graph.read = (data) => {
                let {nodes, edges} = data || {}
                nodes = nodes || []
                edges = edges || []

                nodes.forEach(node => formatNodeModel(node, editorProps.activityConfig))

                data = {nodes, edges}
                $read.apply(graph, [data])
            }

            graph.setMode('edit')
            graph.read(props.data)
            useEditorPlugins(props as any, graph)
            editorState.setGraph(graph)
        }

        function onResize() {
            refresh()
        }

        onMounted(() => {
            const target = context.refs.target as HTMLElement
            target.addEventListener('mouseenter', onMouseenter)
            target.addEventListener('mouseout', onMouseout)
            window.addEventListener('resize', onResize)

            refresh()
        })

        onBeforeUnmount(() => {
            const target = context.refs.target as HTMLElement
            target.removeEventListener('mouseenter', onMouseenter)
            target.removeEventListener('mouseout', onMouseout)
            window.removeEventListener('resize', onResize)

            commander.destroyEvent()
        })

        return () => (
            <div class="vue-flow-editor-canvas" ref="root">
                <div class="vue-flow-editor-canvas-target" ref="target"/>
            </div>
        )
    },
})